package com.hulk.dryad.admin.controller;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hulk.dryad.admin.api.vo.SysOperLogVO;
import com.hulk.dryad.admin.mapstruct.SysOperLogStruct;
import com.hulk.dryad.admin.security.service.AdminUser;
import com.hulk.dryad.common.annotation.Idempotent;
import com.hulk.dryad.common.annotation.PrintlnLog;
import com.hulk.dryad.common.component.R;
import com.hulk.dryad.common.constant.CommonConstants;
import com.hulk.dryad.common.constant.enums.ActionType;
import com.hulk.dryad.common.util.SecurityUtils;
import com.hulk.dryad.common.util.WebUtils;
import com.hulk.dryad.persistence.entity.SysOperLog;
import com.hulk.dryad.manage.provider.service.SysOperLogService;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
import net.dreamlu.mica.ip2region.core.IpInfo;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;


/**
 * <p>
 * 日志表 前端控制器
 * </p>
 *
 * @author hulk
 * @since 2021-03-28
 */
@Api(value = "log", tags = "日志管理模块")
@RestController
@AllArgsConstructor
@RequestMapping("/admin/log")
public class SysLogController {

	private final  SysOperLogService sysOperLogService;
	private final Ip2regionSearcher searcher;
	/**
	 * 分页查询
	 * @param page 分页对象
	 * @param vo 系统日志
	 * @return
	 */
	@ApiOperation(value = "分页查询", notes = "分页查询")
	@PrintlnLog
	@GetMapping("/page" )
	public R getSysOperLogPage(Page page, SysOperLogVO vo) {
		SysOperLog model = SysOperLogStruct.INSTANCE.to(vo);

		LambdaQueryWrapper<SysOperLog> wrapper = Wrappers.lambdaQuery();
		if (StrUtil.isNotBlank(model.getStatus())) {
			wrapper.eq(SysOperLog::getStatus, model.getStatus());
		}

		if (ArrayUtil.isNotEmpty(model.getSearchTime())) {
			wrapper.ge(SysOperLog::getCreatedTime, model.getSearchTime()[0]).le(SysOperLog::getCreatedTime,
					model.getSearchTime()[1]);
		}
		return R.ok(sysOperLogService.page(page, wrapper));
	}


	/**
	 * 通过id查询系统日志
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "通过id查询", notes = "通过id查询")
	@PrintlnLog
	@GetMapping("/{id}" )
	public R getById(@PathVariable("id" ) Long id) {
		SysOperLog model = sysOperLogService.getById(id);
		SysOperLogVO vo = SysOperLogStruct.INSTANCE.from(model);
		return R.ok(vo);
	}

	/**
	 * 新增系统日志
	 * @param vo 系统日志
	 * @return R
	 */
	@ApiOperation(value = "新增系统日志", notes = "新增系统日志")
	@PrintlnLog("新增系统日志" )
	@Idempotent
	@PostMapping
	@PreAuthorize("@pms.hasPermission('admin_sysoperlog_add')" )
	public R save(@Valid @RequestBody SysOperLogVO vo) {
		SysOperLog model = SysOperLogStruct.INSTANCE.to(vo);
		return R.ok(sysOperLogService.save(model));
	}

	/**
	 * 修改系统日志
	 * @param vo 系统日志
	 * @return R
	 */
	@ApiOperation(value = "修改系统日志", notes = "修改系统日志")
	@PrintlnLog("通过id修改系统日志" )
	@Idempotent
	@PutMapping
	@PreAuthorize("@pms.hasPermission('admin_sysoperlog_edit')" )
	public R updateById(@Valid @RequestBody SysOperLogVO vo) {
		SysOperLog model = SysOperLogStruct.INSTANCE.to(vo);
		return R.ok(sysOperLogService.updateById(model));
	}

	/**
	 * 通过id删除系统日志
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "通过id删除系统日志", notes = "通过id删除系统日志")
	@PrintlnLog("通过id删除系统日志" )
	@DeleteMapping("/{id}" )
	@PreAuthorize("@pms.hasPermission('admin_sysoperlog_del')" )
	public R removeById(@PathVariable Long id) {
		return R.ok(sysOperLogService.removeById(id));
	}
	/**
	 * 通过id批量删除系统日志
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "通过id批量删除系统日志", notes = "通过id批量删除系统日志")
	@PrintlnLog("通过id批量删除系统日志" )
	@DeleteMapping("/batch" )
	@PreAuthorize("@pms.hasPermission('admin_sysoperlog_del')" )
	public R removeBatch(@RequestParam List<Long> ids) {
		return R.ok(sysOperLogService.removeByIds(ids));
	}

	/**
	 * 批量插入前端异常日志
	 * @param sysOpreLogVoList 日志实体
	 * @return success/false
	 */
	@ApiOperation(value = "saveBatchLogs", notes = "批量插入前端异常日志")
	@PrintlnLog
	@PostMapping("/logs")
	public R saveBatchLogs(@RequestBody List<SysOperLogVO> sysOpreLogVoList) {
		List<SysOperLog> logs = SysOperLogStruct.INSTANCE.to(sysOpreLogVoList);
		logs.forEach(v->{
			AdminUser admin = SecurityUtils.getUser();
			if (admin != null) {
				v.setUserId(admin.getId());
				v.setUserName(admin.getUsername());
			}
			v.setStatus(CommonConstants.STATUS_FAIL);
			v.setLogType(ActionType.VUE.getValue());
			v.setActionType(ActionType.VUE.getValue());
			String requestIp = WebUtils.getIP();
			v.setRequestIp(requestIp);
			if(StrUtil.isNotEmpty(requestIp)) {
				IpInfo ipInfo = searcher.memorySearch(requestIp);
				if (ipInfo != null) {
					v.setAddress(ipInfo.getAddress());
				}
			}
			HttpServletRequest request = WebUtils.getRequest();
			String  agent =	request.getHeader(HttpHeaders.USER_AGENT);
			UserAgent userAgent = UserAgent.parseUserAgentString(agent);
			OperatingSystem system = userAgent.getOperatingSystem();
			v.setOs(system.getName());
			Browser browser = userAgent.getBrowser();
			v.setBrowser(browser.getName());
			v.setCreatedTime(LocalDateTime.now());
			v.setUpdatedTime(LocalDateTime.now());
		});
		return R.ok(sysOperLogService.saveBatch(logs));
	}
}

